#include "util.h"
#include <cstdarg>

namespace NS_TIEC {
  WString toWString(const String& s) {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    return converter.from_bytes(s);
  }

  WString toWString(const ByteArray& bytes) {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
    WString wstr = convert.from_bytes(bytes.data);
    return wstr;
  }

  String toString(const WString& ws) {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    return converter.to_bytes(ws);
  }

  String toString(const ByteArray& bytes) {
    std::string str(bytes.data, bytes.length);
    return str;
  }

  String toString(Int64 n) {
    return std::to_string(n);
  }

  String toString(float n) {
    return std::to_string(n);
  }

  String toString(double n) {
    return std::to_string(n);
  }

  Int32 toInt32(const String& s) {
    char* error;
    return strtol(s.data(), &error, 10);
  }

  Int64 toInt64(const String& s) {
    char* error;
    return strtoll(s.data(), &error, 10);
  }

  const char* formatChars(const char* format, ...) {
    va_list args;
    va_start(args, format);
    size_t size = std::vsnprintf(nullptr, 0, format, args) + 1;
    std::unique_ptr<char[]> buf(new char[size]);
    std::vsnprintf(buf.get(), size, format, args);
    va_end(args);
    return buf.get();
  }

  String formatString(const char* format, ...) {
    va_list args;
    va_start(args, format);
    const char* res = formatChars(format, args);
    va_end(args);
    return {res};
  }
}